﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace XTYAPI
{
   public abstract class PLC_Framework
    {
        public PLC_Framework()
        {
            RunLog("软PLC系统启动");
            Task.Run(PLCMain);
            Task.Run(WatchDog);
        }
        public CancellationTokenSource CancellationTokenSource { get; set; } = new CancellationTokenSource();

        #region 看门狗
        public event Action<string> EvenvtWatchDog;
        PLC.TON watchDogTime = new PLC.TON(200);
        public uint WatchDogTimeSet
        {
            get { return watchDogTime.PT; }
            set { watchDogTime.PT = value; }
        }
        public uint WatchDogTimeOut
        {
            get { return watchDogTime.ET; }
        }
        public void WatchDog()
        {
            while (true)
            {
                try
                {
                    watchDogTime.IN = true;
                    if (!PLC.FC.M8001 && watchDogTime.Qp)
                    {
                        //避开第一个扫描周期
                        RunLog("软PLC系统看门狗发生");
                        EvenvtWatchDog?.Invoke($"软PLC系统看门狗发生，时间为{watchDogTime.PT}");
                    }
                }
                catch (Exception ex)
                {
                    RunLog($"软PLC系统看门狗发生报错{ex}");
                }
                finally
                {
                    Thread.Sleep(5);
                }
            }
        }
        public void RestDog()
        {
            watchDogTime.IN = false;
        }
        #endregion

        #region 主任务
        public void PLCMain()
        {
            try
            {
                RunLog("软PLC系统内部初始化");
                Begin();
                RunLog("软PLC系统外部初始化");
                SetUp();
                RunLog("软PLC系统初始化完成");
            }
            catch (Exception ex)
            {
                RunLog($"软PLC系统初始化出错--{ex}");
            }

            while (!CancellationTokenSource.IsCancellationRequested)
            {      
                try
                {
                    Loop();
                    PLC.FC.m8001 = false;
                }
                catch (Exception ex)
                {
                    RunLog($"软PLC系统出错--{ex}");
                }
                finally
                {  
                    RestDog();//喂狗
                   Thread.Sleep(1);
                }
            }
            LoopEnd();
        }
        void Begin()
        {
            PLC.FC.m8001 = true;
        }
        void LoopEnd()
        {
            PLC.FC.m8001 = false;
        }
        public void Stop()
        {
            CancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(0.2));
        }
        /// <summary>
        /// 初始化操作
        /// </summary>
        public abstract void SetUp();
        /// <summary>
        /// 循环逻辑
        /// </summary>
        public abstract void Loop();
        public abstract void RunLog(string info);
        #endregion

    }
}
